/*
 * Copyright 2018 xiaomaoguai.com All right reserved. This software is the
 * confidential and proprietary information of xiaomaoguai.com ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with xiaomaoguai.com.
 */

package com.xiaomaoguai.fcp.pre.kepler.tddl.diamond;

import com.alibaba.fastjson.util.TypeUtils;
import com.taobao.diamond.client.Diamond;
import com.taobao.diamond.manager.ManagerListenerAdapter;
import com.xiaomaoguai.fcp.pre.kepler.tddl.exception.TddlRuntimeException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;


/**
 * 类BizDiamondConfig的实现描述：订阅Diamond配置
 *
 * <pre>
 * <code>
 *  &#064;Bean
 *  public BizDiamondConfig testDiamond() {
 *      BizDiamondConfig diamondConfig = new BizDiamondConfig();
 *      diamondConfig.setDataID("com.xiaomaoguai.tom.test");
 *      diamondConfig.setGroupID("DEFAULT_GROUP");
 *      return diamondConfig;
 *  }
 * </code>
 * </pre>
 *
 * 使用：
 *
 * <pre>
 * <code>
 *  &#064;Autowired
 *  private BizDiamondConfig testDiamond;
 *
 *  public String getConfig() {
 *      String userName = testDiamond.getString("userName");
 *      String password = testDiamond.getString("password");
 *      return "userName: " + userName + ", password: " + password;
 *  }
 * </code>
 * </pre>
 *
 * @author chenyao
 * @since 2016年05月06日 下午2:53:24
 */
public class BizDiamondConfig implements InitializingBean {

	/**
	 * 上下行之间的分隔符：<code>\r\n</code>
	 */
	public static final String DEFAULT_LINE_SEPARATOR = "\r\n";

	/**
	 * key/value之间的分隔符：<code>:</code>
	 */
	public static final String DEFAULT_KEY_VALUE_SEPARATOR = ":";

	/**
	 * 默认的groupID：<code>DEFAULT_GROUP</code>
	 */
	public static final String DEFAULT_GROUP_ID = "DEFAULT_GROUP";

	private String groupID = DEFAULT_GROUP_ID;

	private String dataID;

	private String lineSeparator = DEFAULT_LINE_SEPARATOR;

	private String keyValueSeparator = DEFAULT_KEY_VALUE_SEPARATOR;

	private final Map<String, String> configs = new HashMap<>();

	/**
	 * 设置groupID
	 *
	 * @param groupID groupID
	 */
	public void setGroupID(String groupID) {
		this.groupID = groupID;
	}

	/**
	 * 设置dataID
	 *
	 * @param dataID dataID
	 */
	public void setDataID(String dataID) {
		this.dataID = dataID;
	}

	/**
	 * 设置上下行之间的分隔符，默认是 {@value DEFAULT_LINE_SEPARATOR}
	 *
	 * @param lineSeparator 上下行之间的分隔符
	 */
	public void setLineSeparator(String lineSeparator) {
		this.lineSeparator = lineSeparator;
	}

	/**
	 * 设置key/value之间的分隔符，默认是 {@value DEFAULT_KEY_VALUE_SEPARATOR}
	 *
	 * @param keyValueSeparator key/value之间的分隔符
	 */
	public void setKeyValueSeparator(String keyValueSeparator) {
		this.keyValueSeparator = keyValueSeparator;
	}

	@Override
	public void afterPropertiesSet() {
		// 接收diamond消息
		try {
			resolveConfigInfo(Diamond.getConfig(this.dataID, this.groupID, 5000));
		} catch (IOException ex) {
			throw new TddlRuntimeException("dataID=" + this.dataID + ", groupID=" + this.groupID, ex);
		}
		// 增加订阅事件
		Diamond.addListener(this.dataID, this.groupID, new ManagerListenerAdapter() {

			@Override
			public void receiveConfigInfo(String configInfo) {
				resolveConfigInfo(configInfo);
			}
		});
	}

	/**
	 * 解析配置信息
	 *
	 * @param configInfo 配置内容（全量）
	 */
	private void resolveConfigInfo(String configInfo) {
		String[] lines = StringUtils.defaultIfEmpty(configInfo, StringUtils.EMPTY).split(this.lineSeparator);
		for (String line : lines) {
			if (StringUtils.isBlank(line) || line.startsWith("#")) {
				continue;
			}
			String[] split = line.split(this.keyValueSeparator);
			if (split.length >= 2) {
				StringBuilder value = new StringBuilder(split[1]);
				for (int i = 2; i < split.length; i++) {
					value.append(":").append(split[i]);
				}
				this.configs.put(split[0], value.toString());
			}
		}
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public String getConfig(String key) {
		return this.configs.get(key);
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public String getString(String key) {
		return getConfig(key);
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public Boolean getBoolean(String key) {
		return TypeUtils.castToBoolean(getConfig(key));
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public Integer getInteger(String key) {
		return TypeUtils.castToInt(getConfig(key));
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public Long getLong(String key) {
		return TypeUtils.castToLong(getConfig(key));
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public Float getFloat(String key) {
		return TypeUtils.castToFloat(getConfig(key));
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public Double getDouble(String key) {
		return TypeUtils.castToDouble(getConfig(key));
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public BigDecimal getBigDecimal(String key) {
		return TypeUtils.castToBigDecimal(getConfig(key));
	}

	/**
	 * 根据 key 获取 value
	 *
	 * @param key key
	 * @return value
	 */
	public BigInteger getBigInteger(String key) {
		return TypeUtils.castToBigInteger(getConfig(key));
	}
}
